package cc.linker.steplink.crm.merchanth5.service.redis;

import cc.linker.steplink.crm.commons.enums.IntegralEnums;
import cc.linker.steplink.crm.commons.integral.IntegralRequest;
import cc.linker.steplink.crm.commons.utils.CalendarUtils;
import cc.linker.steplink.crm.merchanth5.dao.ScoreActiveCacheDao;
import cc.linker.steplink.crm.merchanth5.dao.VipCustomerLogDao;
import cc.linker.steplink.crm.merchanth5.service.CustomerIntegralService;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;


/**
 * 积分、成长值相关缓存
 */
@Slf4j
@Service
public class ScoreActiveCacheService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private ScoreActiveCacheDao scoreActiveCacheDao;
    @Autowired
    private CustomerIntegralService customerIntegralService;
    @Autowired
    private VipCustomerLogDao vipCustomerLogDao;


    public String shareKey = "scoreActive:share_";
    public String orderNumKey = "scoreActive:orderNum_";
    public String orderAmountKey = "scoreActive:orderAmount_";
    public String orderAmountListKey = "scoreActive:orderAmountList_";
    public String limitKey = "scoreActive:sentLimit_";


    /**
     * 计算消费是否需要赠送积分和成长值
     * @param orgId 机构Id
     * @param orderSn 订单编号
     * @param orderAmount 订单实付金额
     * @param goodsIds 报名下单传 null
     * @param customerId 用户Id
     */
    public void setCache(String orgId, String orderSn, String orderAmount, List<Long> goodsIds, String customerId){
//        int amount = 0;
//        if (!StringUtils.isEmpty(orderAmount) && Integer.valueOf(orderAmount) > 0) {
//            amount = Integer.valueOf(orderAmount);
//        }
        boolean isGoods = true;
        if(null == goodsIds || goodsIds.size() == 0){
            isGoods = false;
        }
        List<Map<String, Object>> saList = scoreActiveCacheDao.listScoreActAll(orgId);
        for(Map<String, Object> sa : saList){
            String rule = (String)sa.get("rule");
            String type = (String)sa.get("type");
            String st = "";
            if("1".equals(type)){
                st = "score";//积分
            }else{
                st = "growth";//成长值
            }
            String activeType = (String)sa.get("activeType");
            if(!StringUtils.isEmpty(rule)){
                if("custom".equals(activeType)){
                    if(isGoods){
                        //自定义任务
                        List<Map<String,Object>> ruList = (List<Map<String,Object>>) JSON.parse(rule);
                        for(Map<String,Object> ru:ruList){
                            String rgid = ru.get("goodsId").toString();
                            if(!StringUtils.isEmpty(ru.get("sendVal"))){
                                String sendVal = ru.get("sendVal").toString();
                                for(Long gid:goodsIds){
                                    if(rgid.equals(gid.toString())){
                                        String oalistkey = orderAmountListKey + orderSn + "_" + customerId + "_" + orgId + "_other_" + st;
                                        Map<String,Object> data = new HashMap<>();
                                        data.put("gid",rgid);
                                        data.put("score",sendVal);
                                        data.put("uuid",UUID.randomUUID().toString());
                                        if("1".equals(ru.get("sendType").toString())){
                                            //只送一次
                                            Boolean member = stringRedisTemplate.opsForSet().isMember(limitKey + customerId, rgid);
                                            if(null == member || !member){
                                                stringRedisTemplate.opsForSet().add(oalistkey, JSON.toJSONString(data));
                                                stringRedisTemplate.expire(oalistkey,90, TimeUnit.DAYS);
//                                                stringRedisTemplate.opsForValue().increment(oakey,Long.valueOf(sendVal));
                                            }
                                        }else{
                                            //每次都送
                                            stringRedisTemplate.opsForSet().add(oalistkey, JSON.toJSONString(data));
                                            stringRedisTemplate.expire(oalistkey,90, TimeUnit.DAYS);
//                                            stringRedisTemplate.opsForValue().increment(oakey,Long.valueOf(sendVal));
                                        }
                                    }
                                }
                            }
                        }
                    }
                }else{
                    //系统任务
                    String oakey = orderAmountKey + orderSn + "_" + customerId + "_" + orgId + "_mall_" + st;
                    Map<String,Object> ruMap = (Map<String,Object>) JSON.parse(rule);
                    ruMap.put("uuid",UUID.randomUUID().toString());
                    stringRedisTemplate.opsForSet().add(oakey,JSON.toJSONString(ruMap));
                    stringRedisTemplate.expire(oakey,90, TimeUnit.DAYS);
                }
            }
        }
    }


    //订单结算赠送缓存中的积分
    public void invoke(String orderSn) {
        invokeCustom(orderSn);
        String oakey = orderAmountKey + orderSn + "_*";
        Set<String> keys = stringRedisTemplate.keys(oakey);
        if(null!=keys && keys.size()>0){
            for(String key:keys){
                String[] param = key.split("_");
                String customerId = param[2];
                String orgId = param[3];
                String type = param[5];
//                List<Long> goodsIds = null;
                Integer orderAmount = 0;
                if(orderSn.startsWith("I")){
                    orderAmount = scoreActiveCacheDao.getIntegralOrderAmount(orderSn);
//                    goodsIds = scoreActiveCacheDao.getIntegralGoodsIdByOrderSn(orderSn);
                }
                if(orderSn.startsWith("E")){
                    orderAmount = scoreActiveCacheDao.getOrderAmount(orderSn);
//                    goodsIds = scoreActiveCacheDao.getGoodsIdByOrderSn(orderSn);
                }
//                if(null != goodsIds && !goodsIds.isEmpty()){
//                    for (Long gid:goodsIds){
//                        stringRedisTemplate.opsForSet().add(limitKey + customerId,gid.toString());
//                    }
//                }

                String sourceFieldName = "";
                if("mall".equals(type)){
                    sourceFieldName = IntegralEnums.mallSystem.toString();
                }
                if("other".equals(type)){
                    sourceFieldName = IntegralEnums.other.toString();
                }
                String integralFieldName = "";
                int sendWx = 0;
                if(key.endsWith("score")){
                    integralFieldName = IntegralEnums.customerScore.toString();
                    sendWx = 1;
                }
                if(key.endsWith("growth")){
                    integralFieldName = IntegralEnums.customerGrowthScore.toString();
                    sendWx = 2;
                }
                Set<String> members = stringRedisTemplate.opsForSet().members(key);
                if(null!=members && members.size()>0){
                    Integer allScore = 0;
                    for(String me:members){
                        Map<String,Object> rule = (Map<String,Object>)JSON.parse(me);
                        int money = Integer.parseInt(rule.get("val1").toString())*100;
                        int score = Integer.parseInt(rule.get("val2").toString());
                        if (orderAmount >= money && money>0) {
                            allScore = (orderAmount / money) * score;
                        }
                    }
                    if(allScore>0){
                        this.customerIntegralService.addIntegralCustomerLog(customerId,"购买商品赠送", integralFieldName,allScore.toString(),sourceFieldName,orgId);
                        if(1==sendWx){
                            Map<String,Object> logParam = new HashMap<>();
                            logParam.put("scoreLogId", UUID.randomUUID().toString());
                            logParam.put("customerId", customerId);
                            logParam.put("scoreValue", allScore);
                            logParam.put("scoreType", 7);
                            logParam.put("actionRemark", "购买商品赠送"+allScore+"积分");
                            logParam.put("sendWx", sendWx);
                            scoreActiveCacheDao.addLog(logParam);
                        }
                        if(2==sendWx){
                            Map<String, Object> log = new HashMap<>();
                            log.put("logId", UUID.randomUUID().toString());
                            log.put("customerId", customerId);
                            log.put("growthValue", allScore);
                            log.put("growthType", 7);
                            log.put("actionRemark", "购买商品赠送"+allScore+"成长值");
                            vipCustomerLogDao.addGrowth(log);
                        }
                        stringRedisTemplate.delete(key);
                    }
                }
            }
        }
    }

    //订单结算赠送缓存中的积分
    public void invokeCustom(String orderSn) {
        String oalistkey = orderAmountListKey + orderSn + "_*";
        Set<String> keys = stringRedisTemplate.keys(oalistkey);
        if(null!=keys && keys.size()>0){
            for(String key:keys){
                String[] param = key.split("_");
                String customerId = param[2];
                String orgId = param[3];
                String type = param[5];
                List<Long> goodsIds = null;
                if(orderSn.startsWith("I")){
                    goodsIds = scoreActiveCacheDao.getIntegralGoodsIdByOrderSn(orderSn);
                }
                if(orderSn.startsWith("E")){
                    goodsIds = scoreActiveCacheDao.getGoodsIdByOrderSn(orderSn);
                }
                if(null != goodsIds && !goodsIds.isEmpty()){
                    for (Long gid:goodsIds){
                        stringRedisTemplate.opsForSet().add(limitKey + customerId,gid.toString());
                    }
                }
                String sourceFieldName = "";
                if("mall".equals(type)){
                    sourceFieldName = IntegralEnums.mallSystem.toString();
                }
                if("other".equals(type)){
                    sourceFieldName = IntegralEnums.other.toString();
                }
                String integralFieldName = "";
                int sendWx = 0;
                if(key.endsWith("score")){
                    integralFieldName = IntegralEnums.customerScore.toString();
                    sendWx = 1;
                }
                if(key.endsWith("growth")){
                    integralFieldName = IntegralEnums.customerGrowthScore.toString();
                    sendWx = 2;
                }
                Set<String> members = stringRedisTemplate.opsForSet().members(key);
                Long allScore = 0L;
                if(null!=members && !members.isEmpty()){
                    for(String me:members){
                        Map<String,Object> data = (Map<String,Object>)JSON.parse(me);
                        Long gid = Long.parseLong(data.get("gid").toString());
                        Long score = Long.parseLong(data.get("score").toString());
                        if(goodsIds!=null && goodsIds.contains(gid)){
                            allScore = allScore + score;
                        }
                    }
                }
                this.customerIntegralService.addIntegralCustomerLog(customerId,"购买指定商品赠送", integralFieldName,allScore.toString(),sourceFieldName,orgId);
                if(1==sendWx){
                   Map<String,Object> logParam = new HashMap<>();
                   logParam.put("scoreLogId", UUID.randomUUID().toString());
                   logParam.put("customerId", customerId);
                   logParam.put("scoreValue", allScore.toString());
                   logParam.put("scoreType", 7);
                   logParam.put("actionRemark", "购买指定商品赠送"+allScore+"积分");
                   logParam.put("sendWx", sendWx);
                   scoreActiveCacheDao.addLog(logParam);
                }
                if(2==sendWx){
                    Map<String, Object> log = new HashMap<>();
                    log.put("logId", UUID.randomUUID().toString());
                    log.put("customerId", customerId);
                    log.put("growthValue", allScore);
                    log.put("growthType", 7);
                    log.put("actionRemark", "购买指定商品赠送"+allScore+"成长值");
                    vipCustomerLogDao.addGrowth(log);
                }
                stringRedisTemplate.delete(key);
            }
        }
    }


    public void cacheOrderNum(String orderSn){
        LOGGER.info("<-----cacheOrderNum1----->"+orderSn);
        Map<String,Object> orderInfo = null;
//        if(orderSn.startsWith("Y")){
//            orderInfo = scoreActiveCacheDao.getEnrollOrder(orderSn);
//        }
        if(orderSn.startsWith("E")){
            orderInfo = scoreActiveCacheDao.getOrder(orderSn);
        }
//        if(orderSn.startsWith("I")){
//            orderInfo = scoreActiveCacheDao.getIntegralOrder(orderSn);
//        }

        if(orderInfo == null){
            LOGGER.error("未知订单号"+orderSn);
            return;
        }
        //记录当天用户结算完的订单数
        List<Map<String,Object>> sList = scoreActiveCacheDao.getActStatus(orderInfo.get("orgId").toString());
        if(null!=sList && sList.size()>0){
            for(Map<String,Object> s:sList){
                String type;
                if("1".equals(s.get("type").toString())){
                    type = "score";
                }else{
                    type = "growth";
                }
                SimpleDateFormat format = new SimpleDateFormat(CalendarUtils.DAY_FORMAT);
                String today = format.format(CalendarUtils.getToday());
                if("order".equals(s.get("activeType").toString())){
                    String orderNum = orderNumKey + today + "_" + orderInfo.get("orgId") + "_" + orderInfo.get("customerId") + "_" + type;
                    LOGGER.info("<-----cacheOrderNum2order----->"+JSON.toJSONString(s));
                    stringRedisTemplate.opsForValue().increment(orderNum, 1L);
                    stringRedisTemplate.expire(orderNum,90, TimeUnit.DAYS);
                }
                if("deal".equals(s.get("activeType").toString())){
                    //已经推荐成交过的就不统计了
                    Boolean customerId = stringRedisTemplate.opsForSet().isMember(shareKey + "deal_"+type+"_given", orderInfo.get("customerId").toString());
                    if(null == customerId || !customerId){
                        String shareDeal = shareKey+"deal_" + today + "_" + orderInfo.get("orgId") + "_" + orderInfo.get("salerId") + "_" + type;
                        LOGGER.info("<-----cacheOrderNum2deal----->"+JSON.toJSONString(s));
                        stringRedisTemplate.opsForValue().increment(shareDeal, 1L);
                        stringRedisTemplate.expire(shareDeal,30, TimeUnit.DAYS);
                        stringRedisTemplate.opsForSet().add(shareKey + "deal_"+type+"_given",orderInfo.get("customerId").toString());
                    }
                }

            }
        }
    }
}
